<?php
if(!defined('IN_WOGU')) {
    exit('Access Denied');
}

class Upload
{
    //上传成功并且格式正确的文件
    protected $_files = array();
    
    //上传失败的文件
    protected $_failed = array();
    
    //文件大小上限，默认为5M
    public $maxsize = 5242880;
    
    //允许的文件格式
    public $exts = array('jpg', 'psd', 'ai', 'eps', 'cdr');
    
    //允许的MIME_TYPE
    public $mimetypes = array();
    
    //文件类型目录
    public $type = '';
    
    //自动对文件按扩展名分类，但$type的优先级高于$autocat
    public $autocat = true;
    
    //文件上传的根目录
    public $attachmentdir = 'attachment/sources/';
    
    //上传失败相关常量定义
    const TMP_NAME_EMPTY = -1;
    const UPLOAD_ERROR = -2;
    const FILE_SIZE_IS_ZERO = -3;
    const FILE_SIZE_TO_BIG = -4;
    const EXT_DENY = -5;
    const MIMETYPE_DENY = -6;
    const MOVE_UPLOADED_FILE_FAILED = -7;
    
    public function __construct() {}
    
    public function addFiles($files, $forcenames = '') {
        if(is_array($files['name']) && !empty($files['name'])) {
            foreach($files['name'] as $k => $v) {
                $file = array('name' => $v, 'type' => $files['type'][$k], 'tmp_name' => $files['tmp_name'][$k], 'size' => $files['size'][$k], 'error' => $files['error'][$k], 'ext' => fileext($v));
                $file['forcename'] = isset($forcenames[$k]) ? $forcenames[$k] : '';
                
                if($this->isUpload($file)) {
                    $this->_files[] = $file;
                }
            }
        } else {
            $file = array('name' => $files['name'], 'type' => $files['type'], 'tmp_name' => $files['tmp_name'], 'size' => $files['size'], 'error' => $files['error'], 'ext' => fileext($files['name']));
            $file['forcename'] = '' == $forcenames ? '' : $forcenames;
            
            if($this->isUpload($file)) {
                $this->_files[] = $file;
            }
        }
        
        if(!empty($this->mimetypes)) {
            $this->checkMimeType();    
        }
    }
    
    public function setFiles($files, $forcenames = '') {
        $this->_files = $this->_failed = array();
        $this->addFiles($files, $forcenames);
    }
    
    //上传是否成功
    public function isUpload($file) {
        if(empty($file['name'])) {
            return false;
        }
        
        $error = 0;
        if(empty($file['tmp_name'])) {
            $error = self::TMP_NAME_EMPTY;
        } elseif($file['error'] != 0) {
            $error = self::UPLOAD_ERROR;
        } elseif($file['size'] == 0) {
            $error = self::FILE_SIZE_IS_ZERO;
        } elseif($file['size'] > $this->maxsize) {
            $error = self::FILE_SIZE_TO_BIG;
        } elseif(!in_array($file['ext'], $this->exts)) {
            $error = self::EXT_DENY;
        }
        
        if($error !== 0) {
            $this->_failed[] = array('filename' => $file['name'], 'error' => $error);
            return false;    
        }
        
        return true;
    }
    
    public function checkMimeType() {
        if(empty($this->_files)) {
            return false;    
        }
        
        $finfo = finfo_open(FILEINFO_MIME_TYPE);
        
        foreach($this->_files as $k => $v) {
            $mimetype = finfo_file($finfo, $v);
            if(!in_array($mimetype, $this->mimetypes)) {
                $this->_failed[] = array('filename' => $this->_files[$k]['name'], 'error' => self::MIMETYPE_DENY);
                $this->_files[$k] = null;
                unset($this->_files[$k]);
            }
        }

        finfo_close($finfo);
    }
    
    public function upload() {
        if(empty($this->_files)) {
            return false;    
        }

        $dir = WOGU_ROOT . $this->attachmentdir;
        foreach($this->_files as $k => $file) {
            if('' != $file['forcename']) {
                $path = $dir . $file['forcename'];
                $savepath = $file['forcename'];
            } else {
                $dir1 = ($this->type != '' ? ($this->type . '/') : ($this->autocat ? ($file['ext'] . '/') : '')) . date('Ym') . '/' . date('d') . '/';
                $dir2 = $dir . $dir1;
                if(!is_dir($dir2)) {
                    create_dir($dir2);
                }
                
                $filename = date('His').strtolower(random(16)) . '.' . $file['ext'];
                $path = $dir2 . $filename;
                $savepath = $dir1 . $filename;
            }

            if(!move_uploaded_file($file['tmp_name'], $path)) {
                $this->_failed[] = array('filename' => $this->_files[$k]['name'], 'error' => self::MOVE_UPLOADED_FILE_FAILED);
                $this->_files[$k] = null;
                unset($this->_files[$k]);
                continue;
            }
            
            chmod($path, 0777);
            $this->_files[$k]['save_path'] = $savepath;
        }
        
        return $this->_files;
    }
    
    public function getFailed() {
        return $this->_failed;
    }
}